﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.MountAndBlade.View.Scripts.CharacterDebugSpawner
// Assembly: TaleWorlds.MountAndBlade.View, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 61152EB8-513B-4D4A-8AC0-0D1465C6CF6C
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\Modules\Native\bin\Win64_Shipping_Client\TaleWorlds.MountAndBlade.View.dll

using TaleWorlds.Core;
using TaleWorlds.Engine;
using TaleWorlds.Library;

#nullable disable
namespace TaleWorlds.MountAndBlade.View.Scripts
{
  public class CharacterDebugSpawner : ScriptComponentBehavior
  {
    private readonly ActionIndexCache[] _actionIndices = new ActionIndexCache[97]
    {
      ActionIndexCache.Create("act_start_conversation"),
      ActionIndexCache.Create("act_stand_conversation"),
      ActionIndexCache.Create("act_start_angry_conversation"),
      ActionIndexCache.Create("act_stand_angry_conversation"),
      ActionIndexCache.Create("act_start_sad_conversation"),
      ActionIndexCache.Create("act_stand_sad_conversation"),
      ActionIndexCache.Create("act_start_happy_conversation"),
      ActionIndexCache.Create("act_stand_happy_conversation"),
      ActionIndexCache.Create("act_start_busy_conversation"),
      ActionIndexCache.Create("act_stand_busy_conversation"),
      ActionIndexCache.Create("act_explaining_conversation"),
      ActionIndexCache.Create("act_introduction_conversation"),
      ActionIndexCache.Create("act_wondering_conversation"),
      ActionIndexCache.Create("act_unknown_conversation"),
      ActionIndexCache.Create("act_friendly_conversation"),
      ActionIndexCache.Create("act_offer_conversation"),
      ActionIndexCache.Create("act_negative_conversation"),
      ActionIndexCache.Create("act_affermative_conversation"),
      ActionIndexCache.Create("act_secret_conversation"),
      ActionIndexCache.Create("act_remember_conversation"),
      ActionIndexCache.Create("act_laugh_conversation"),
      ActionIndexCache.Create("act_threat_conversation"),
      ActionIndexCache.Create("act_scared_conversation"),
      ActionIndexCache.Create("act_flirty_conversation"),
      ActionIndexCache.Create("act_thanks_conversation"),
      ActionIndexCache.Create("act_farewell_conversation"),
      ActionIndexCache.Create("act_troop_cavalry_sword"),
      ActionIndexCache.Create(nameof (act_inventory_idle_start)),
      ActionIndexCache.Create("act_inventory_idle"),
      ActionIndexCache.Create("act_character_developer_idle"),
      ActionIndexCache.Create("act_inventory_cloth_equip"),
      ActionIndexCache.Create("act_inventory_glove_equip"),
      ActionIndexCache.Create("act_jump"),
      ActionIndexCache.Create("act_jump_loop"),
      ActionIndexCache.Create("act_jump_end"),
      ActionIndexCache.Create("act_jump_end_hard"),
      ActionIndexCache.Create("act_jump_left_stance"),
      ActionIndexCache.Create("act_jump_loop_left_stance"),
      ActionIndexCache.Create("act_jump_end_left_stance"),
      ActionIndexCache.Create("act_jump_end_hard_left_stance"),
      ActionIndexCache.Create("act_jump_forward"),
      ActionIndexCache.Create("act_jump_forward_loop"),
      ActionIndexCache.Create("act_jump_forward_end"),
      ActionIndexCache.Create("act_jump_forward_end_hard"),
      ActionIndexCache.Create("act_jump_forward_left_stance"),
      ActionIndexCache.Create("act_jump_forward_loop_left_stance"),
      ActionIndexCache.Create("act_jump_forward_end_left_stance"),
      ActionIndexCache.Create("act_jump_forward_end_hard_left_stance"),
      ActionIndexCache.Create("act_jump_backward"),
      ActionIndexCache.Create("act_jump_backward_loop"),
      ActionIndexCache.Create("act_jump_backward_end"),
      ActionIndexCache.Create("act_jump_backward_end_hard"),
      ActionIndexCache.Create("act_jump_backward_left_stance"),
      ActionIndexCache.Create("act_jump_backward_loop_left_stance"),
      ActionIndexCache.Create("act_jump_backward_end_left_stance"),
      ActionIndexCache.Create("act_jump_backward_end_hard_left_stance"),
      ActionIndexCache.Create("act_jump_forward_right"),
      ActionIndexCache.Create("act_jump_forward_right_left_stance"),
      ActionIndexCache.Create("act_jump_forward_left"),
      ActionIndexCache.Create("act_jump_forward_left_left_stance"),
      ActionIndexCache.Create("act_jump_right"),
      ActionIndexCache.Create("act_jump_right_loop"),
      ActionIndexCache.Create("act_jump_right_end"),
      ActionIndexCache.Create("act_jump_right_end_hard"),
      ActionIndexCache.Create("act_jump_left"),
      ActionIndexCache.Create("act_jump_left_loop"),
      ActionIndexCache.Create("act_jump_left_end"),
      ActionIndexCache.Create("act_jump_left_end_hard"),
      ActionIndexCache.Create("act_jump_loop_long"),
      ActionIndexCache.Create("act_jump_loop_long_left_stance"),
      ActionIndexCache.Create("act_throne_sit_down_from_front"),
      ActionIndexCache.Create("act_throne_stand_up_to_front"),
      ActionIndexCache.Create("act_throne_sit_idle"),
      ActionIndexCache.Create("act_sit_down_from_front"),
      ActionIndexCache.Create("act_sit_down_from_right"),
      ActionIndexCache.Create("act_sit_down_from_left"),
      ActionIndexCache.Create("act_sit_down_on_floor_1"),
      ActionIndexCache.Create("act_sit_down_on_floor_2"),
      ActionIndexCache.Create("act_sit_down_on_floor_3"),
      ActionIndexCache.Create("act_stand_up_to_front"),
      ActionIndexCache.Create("act_stand_up_to_right"),
      ActionIndexCache.Create("act_stand_up_to_left"),
      ActionIndexCache.Create("act_stand_up_floor_1"),
      ActionIndexCache.Create("act_stand_up_floor_2"),
      ActionIndexCache.Create("act_stand_up_floor_3"),
      ActionIndexCache.Create("act_sit_1"),
      ActionIndexCache.Create("act_sit_2"),
      ActionIndexCache.Create("act_sit_3"),
      ActionIndexCache.Create("act_sit_4"),
      ActionIndexCache.Create("act_sit_5"),
      ActionIndexCache.Create("act_sit_6"),
      ActionIndexCache.Create("act_sit_7"),
      ActionIndexCache.Create("act_sit_8"),
      ActionIndexCache.Create("act_sit_idle_on_floor_1"),
      ActionIndexCache.Create("act_sit_idle_on_floor_2"),
      ActionIndexCache.Create("act_sit_idle_on_floor_3"),
      ActionIndexCache.Create("act_sit_conversation")
    };
    private readonly ActionIndexCache act_inventory_idle_start = ActionIndexCache.Create(nameof (act_inventory_idle_start));
    public readonly ActionIndexCache PoseAction = ActionIndexCache.Create("act_walk_idle_unarmed");
    public string LordName = "main_hero";
    public bool IsWeaponWielded;
    private Vec2 MovementDirection;
    private float MovementSpeed;
    private float PhaseDiff;
    private float Time;
    private float ActionSetTimer;
    private float ActionChangeInterval;
    private float MovementDirectionChange;
    private static MBGameManager _editorGameManager = (MBGameManager) null;
    private static int _editorGameManagerRefCount = 0;
    private static bool isFinished = false;
    private static int gameTickFrameNo = -1;
    private bool CreateFaceImmediately = true;
    private AgentVisuals _agentVisuals;

    public uint ClothColor1 { get; private set; }

    public uint ClothColor2 { get; private set; }

    protected override void OnInit()
    {
      base.OnInit();
      this.ClothColor1 = uint.MaxValue;
      this.ClothColor2 = uint.MaxValue;
    }

    protected override void OnEditorInit()
    {
      base.OnEditorInit();
      if (CharacterDebugSpawner._editorGameManager == null)
        CharacterDebugSpawner._editorGameManager = (MBGameManager) new EditorGameManager();
      ++CharacterDebugSpawner._editorGameManagerRefCount;
    }

    protected override void OnEditorTick(float dt)
    {
      if (!CharacterDebugSpawner.isFinished && CharacterDebugSpawner.gameTickFrameNo != Utilities.EngineFrameNo)
      {
        CharacterDebugSpawner.gameTickFrameNo = Utilities.EngineFrameNo;
        CharacterDebugSpawner.isFinished = !CharacterDebugSpawner._editorGameManager.DoLoadingForGameManager();
      }
      if (Game.Current != null && this._agentVisuals == null)
      {
        this.MovementDirection.x = MBRandom.RandomFloatNormal;
        this.MovementDirection.y = MBRandom.RandomFloatNormal;
        double num = (double) this.MovementDirection.Normalize();
        this.MovementSpeed = (float) ((double) MBRandom.RandomFloat * 9.0 + 1.0);
        this.PhaseDiff = MBRandom.RandomFloat;
        this.MovementDirectionChange = MBRandom.RandomFloatNormal * 3.14159274f;
        this.Time = 0.0f;
        this.ActionSetTimer = 0.0f;
        this.ActionChangeInterval = (float) ((double) MBRandom.RandomFloat * 0.5 + 0.5);
        this.SpawnCharacter();
      }
      MatrixFrame globalFrame = this._agentVisuals.GetVisuals().GetGlobalFrame();
      this._agentVisuals.GetVisuals().SetFrame(ref globalFrame);
      Vec3 vec3 = new Vec3(this.MovementDirection);
      vec3.RotateAboutZ(this.MovementDirectionChange * dt);
      this.MovementDirection.x = vec3.x;
      this.MovementDirection.y = vec3.y;
      this._agentVisuals.SetAgentLocalSpeed(this.MovementDirection * (float) ((double) this.MovementSpeed * ((double) MathF.Sin(this.PhaseDiff + this.Time) * 0.5) + 2.0));
      this.Time += dt;
      if ((double) this.Time - (double) this.ActionSetTimer <= (double) this.ActionChangeInterval)
        return;
      this.ActionSetTimer = this.Time;
      this._agentVisuals.SetAction(this._actionIndices[MBRandom.RandomInt(this._actionIndices.Length)], 0.0f, true);
    }

    protected override void OnRemoved(int removeReason)
    {
      base.OnRemoved(removeReason);
      this.Reset();
      --CharacterDebugSpawner._editorGameManagerRefCount;
      if (CharacterDebugSpawner._editorGameManagerRefCount != 0)
        return;
      CharacterDebugSpawner._editorGameManager = (MBGameManager) null;
      CharacterDebugSpawner.isFinished = false;
    }

    protected override void OnEditorVariableChanged(string variableName)
    {
      base.OnEditorVariableChanged(variableName);
      switch (variableName)
      {
        case "LordName":
          BasicCharacterObject basicCharacterObject = Game.Current.ObjectManager.GetObject<BasicCharacterObject>(this.LordName);
          AgentVisualsData agentVisualsData = this._agentVisuals.GetCopyAgentVisualsData();
          agentVisualsData.BodyProperties(basicCharacterObject.GetBodyProperties((Equipment) null)).SkeletonType(basicCharacterObject.IsFemale ? SkeletonType.Female : SkeletonType.Male).ActionSet(MBGlobals.GetActionSetWithSuffix(agentVisualsData.MonsterData, basicCharacterObject.IsFemale, "_poses")).Equipment(basicCharacterObject.Equipment).UseMorphAnims(true);
          this._agentVisuals.Refresh(false, agentVisualsData, false);
          break;
        case "PoseAction":
          this._agentVisuals?.SetAction(this.PoseAction, 0.0f, true);
          break;
        case "IsWeaponWielded":
          this.WieldWeapon(CharacterCode.CreateFrom(Game.Current.ObjectManager.GetObject<BasicCharacterObject>(this.LordName)));
          break;
      }
    }

    public void SetClothColors(uint color1, uint color2)
    {
      this.ClothColor1 = color1;
      this.ClothColor2 = color2;
    }

    public void SpawnCharacter()
    {
      BasicCharacterObject character = Game.Current.ObjectManager.GetObject<BasicCharacterObject>(this.LordName);
      if (character == null)
        return;
      this.InitWithCharacter(CharacterCode.CreateFrom(character));
    }

    public void Reset() => this._agentVisuals?.Reset();

    public void InitWithCharacter(CharacterCode characterCode)
    {
      GameEntity empty = GameEntity.CreateEmpty(this.GameEntity.Scene, false);
      empty.Name = "TableauCharacterAgentVisualsEntity";
      Monster baseMonsterFromRace = TaleWorlds.Core.FaceGen.GetBaseMonsterFromRace(characterCode.Race);
      this._agentVisuals = AgentVisuals.Create(new AgentVisualsData().Equipment(characterCode.CalculateEquipment()).BodyProperties(characterCode.BodyProperties).Race(characterCode.Race).Frame(empty.GetGlobalFrame()).SkeletonType(characterCode.IsFemale ? SkeletonType.Female : SkeletonType.Male).Entity(empty).ActionSet(MBGlobals.GetActionSetWithSuffix(baseMonsterFromRace, characterCode.IsFemale, "_facegen")).ActionCode(this.act_inventory_idle_start).Scene(this.GameEntity.Scene).Monster(baseMonsterFromRace).PrepareImmediately(this.CreateFaceImmediately).Banner(characterCode.Banner).ClothColor1(this.ClothColor1).ClothColor2(this.ClothColor2), nameof (CharacterDebugSpawner), false, false, false);
      this._agentVisuals.SetAction(this.PoseAction, MBRandom.RandomFloat, true);
      this.GameEntity.AddChild(empty);
      this.WieldWeapon(characterCode);
      this._agentVisuals.GetVisuals().GetSkeleton().TickAnimationsAndForceUpdate(0.1f, this._agentVisuals.GetVisuals().GetGlobalFrame(), true);
    }

    public void WieldWeapon(CharacterCode characterCode)
    {
      if (!this.IsWeaponWielded)
        return;
      int rightWieldedItemIndex = -1;
      int leftWieldedItemIndex = -1;
      Equipment equipment = characterCode.CalculateEquipment();
      for (int index = 0; index < 4; ++index)
      {
        EquipmentElement equipmentElement = equipment[index];
        if (equipmentElement.Item?.PrimaryWeapon != null)
        {
          if (leftWieldedItemIndex == -1)
          {
            equipmentElement = equipment[index];
            if (equipmentElement.Item.ItemFlags.HasAnyFlag<ItemFlags>(ItemFlags.HeldInOffHand))
              leftWieldedItemIndex = index;
          }
          if (rightWieldedItemIndex == -1)
          {
            equipmentElement = equipment[index];
            if (equipmentElement.Item.PrimaryWeapon.WeaponFlags.HasAnyFlag<WeaponFlags>(WeaponFlags.WeaponMask))
              rightWieldedItemIndex = index;
          }
        }
      }
      if (rightWieldedItemIndex == -1 && leftWieldedItemIndex == -1)
        return;
      AgentVisualsData agentVisualsData = this._agentVisuals.GetCopyAgentVisualsData();
      agentVisualsData.RightWieldedItemIndex(rightWieldedItemIndex).LeftWieldedItemIndex(leftWieldedItemIndex).ActionCode(this.PoseAction);
      this._agentVisuals.Refresh(false, agentVisualsData, false);
    }
  }
}
